package com.xiaoyang.system.service.sysuser.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xiaoyang.common.core.constants.HttpConstants;
import com.xiaoyang.common.core.domain.LoginUser;
import com.xiaoyang.common.core.domain.R;
import com.xiaoyang.common.core.domain.vo.LoginUserVO;
import com.xiaoyang.common.core.enums.ResultCode;
import com.xiaoyang.common.core.enums.UserIdentity;
import com.xiaoyang.common.security.exception.ServiceException;
import com.xiaoyang.common.security.service.TokenService;
import com.xiaoyang.system.domain.sysuser.SysUser;
import com.xiaoyang.system.domain.sysuser.dto.SysUserSaveDTO;
import com.xiaoyang.system.mapper.sysuser.SysUserMapper;
import com.xiaoyang.system.service.sysuser.ISysUserService;
import com.xiaoyang.system.utils.BCryptUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

@Slf4j
@Service
@RefreshScope
public class SysUserServiceImpl implements ISysUserService {

    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private TokenService tokenService;

    @Value("${jwt.secret}")
    private String secret;

    /**
     * 管理员登录
     * @param userAccount
     * @param password
     * @return
     */
    @Override
    public R<String> login(String userAccount, String password) {
        // 通过账号在数据库中查询
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        // select password from tb_sys_user where user_account = #{userAccount}
        SysUser sysUser = sysUserMapper.selectOne(queryWrapper.
                select(SysUser::getUserId, SysUser::getPassword, SysUser::getNickName).
                eq(SysUser::getUserAccount, userAccount));

        if (sysUser == null) {
            // 没有找到这个用户
            log.info("用户不存在!");
            return R.fail(ResultCode.FAILED_USER_NOT_EXISTS);
        }
        if (BCryptUtils.matchesPassword(password, sysUser.getPassword())) {
            // 密码匹配--登录成功
            // 生成token
            log.info("用户登录成功!");
            return R.ok(tokenService.createToken(sysUser.getUserId(), secret,
                    UserIdentity.ADMIN.getValue(), sysUser.getNickName(), null));
        }
        // 用户名或密码错误
        return R.fail(ResultCode.FAILED_LOGIN);
    }

    /**
     * 新增管理员
     * @param sysUserSaveDTO
     * @return
     */
    @Override
    public int add(SysUserSaveDTO sysUserSaveDTO) {
        // 查询是否存在用户
        List<SysUser> sysUserList = sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getUserAccount, sysUserSaveDTO.getUserAccount()));

        // 用户已存在
        if (CollectionUtil.isNotEmpty(sysUserList)) {
            // 自定义异常
            throw new ServiceException(ResultCode.AILED_USER_EXISTS);
        }

        // TDO转实体
        SysUser sysUser = new SysUser();
        sysUser.setUserAccount(sysUserSaveDTO.getUserAccount());
        sysUser.setPassword(BCryptUtils.encryptPassword(sysUserSaveDTO.getPassword())); // 加密
        sysUser.setUpdateBy(100L);
        sysUser.setUpdateTime(LocalDateTime.now());

        return sysUserMapper.insert(sysUser);
    }

    /**
     * 获取当前登录用户信息
     * @param token
     * @return
     */
    @Override
    public R<LoginUserVO> info(String token, String secret) {
        if (StrUtil.isNotEmpty(token) &&
                token.startsWith(HttpConstants.PREFIX)) {
            token = token.replaceFirst(HttpConstants.PREFIX, StrUtil.EMPTY);
        }
        LoginUser loginUser = tokenService.getLoginUser(token, secret);
        if (loginUser == null) {
            return R.fail();
        }

        // 返回给前端
        LoginUserVO loginUserVO = new LoginUserVO();
        loginUserVO.setNickName(loginUser.getNickName());

        return R.ok(loginUserVO);
    }

    /**
     * 退出登录
     * @param token
     */
    @Override
    public boolean logout(String token) {
        if (StrUtil.isNotEmpty(token) &&
                token.startsWith(HttpConstants.PREFIX)) {
            token = token.replaceFirst(HttpConstants.PREFIX, StrUtil.EMPTY);
        }
        return tokenService.DeleteLoginUser(token, secret);
    }
}
